package com.lcy.web.utils;

import com.jfinal.kit.HashKit;
import com.jfinal.kit.LogKit;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import java.awt.*;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * Created by loucunyin on 2016/12/15 0015.
 * 图片验证码
 */
public class ImageCaptcha extends Render {
    private static final int WIDTH = 108;
    private static final int HEIGHT = 40;
    private static final String[] strArr = new String[]{"3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"};
    private static final Font[] RANDOM_FONT = new Font[]{new Font("nyala", 1, 38), new Font("Arial", 1, 32), new Font("Bell MT", 1, 32), new Font("Credit valley", 1, 34), new Font("Impact", 1, 32), new Font("Monospaced", 1, 40)};

    private static String NAME = "captcha";

    private String mCaptcha;
    private BufferedImage mImage;

    public ImageCaptcha() {
    }

    public void render() {
        initImage();

        Cookie cookie = new Cookie(NAME, mCaptcha);
        cookie.setMaxAge(1800);
        cookie.setPath("/");

        try {
            cookie.setHttpOnly(true);
        } catch (Exception var16) {
            LogKit.logNothing(var16);
        }

        this.response.addCookie(cookie);
        this.response.setHeader("Pragma", "no-cache");
        this.response.setHeader("Cache-Control", "no-cache");
        this.response.setDateHeader("Expires", 0L);
        this.response.setContentType("image/jpeg");
        ServletOutputStream sos = null;

        try {
            sos = this.response.getOutputStream();
            ImageIO.write(mImage, "jpeg", sos);
        } catch (IOException var17) {
            if(getDevMode()) {
                throw new RenderException(var17);
            }
        } catch (Exception var18) {
            throw new RenderException(var18);
        } finally {
            if(sos != null) {
                try {
                    sos.close();
                } catch (IOException var15) {
                    LogKit.logNothing(var15);
                }
            }

        }
    }

    private void initImage(){
        if(mImage == null){
            mImage = new BufferedImage(108, 40, 1);
            mCaptcha = this.drawGraphic(mImage);
            mCaptcha = mCaptcha.toUpperCase();
            mCaptcha = HashKit.md5(mCaptcha);
        }
    }

    private String drawGraphic(BufferedImage image) {
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.setColor(this.getRandColor(200, 250));
        g.fillRect(0, 0, 108, 40);
        Random random = new Random();
        g.setFont(RANDOM_FONT[random.nextInt(RANDOM_FONT.length)]);

        Color color;
        for(int sRand = 0; sRand < 10; ++sRand) {
            color = this.getRandColor(120, 200);
            g.setColor(color);
            g.drawOval(random.nextInt(108), random.nextInt(40), 5 + random.nextInt(10), 5 + random.nextInt(10));
            color = null;
        }

        String var11 = "";

        for(int bs = 0; bs < 4; ++bs) {
            String curve = String.valueOf(strArr[random.nextInt(strArr.length)]);
            var11 = var11 + curve;
            int degree = random.nextInt(28);
            if(bs % 2 == 0) {
                degree *= -1;
            }

            int x = 22 * bs;
            byte y = 21;
            g.rotate(Math.toRadians((double)degree), (double)x, (double)y);
            color = this.getRandColor(20, 130);
            g.setColor(color);
            g.drawString(curve, x + 8, y + 10);
            g.rotate(-Math.toRadians((double)degree), (double)x, (double)y);
            color = null;
        }

        g.setColor(this.getRandColor(0, 60));
        BasicStroke var12 = new BasicStroke(3.0F);
        g.setStroke(var12);
        QuadCurve2D.Double var13 = new QuadCurve2D.Double(0.0D, (double)(random.nextInt(32) + 4), 54.0D, 20.0D, 108.0D, (double)(random.nextInt(32) + 4));
        g.draw(var13);
        g.dispose();
        return var11;
    }

    private Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if(fc > 255) {
            fc = 255;
        }

        if(bc > 255) {
            bc = 255;
        }

        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    public String getCaptcha() {
        initImage();
        return mCaptcha;
    }
}
